package com.meilai.project.service.business.workbench.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.meilai.project.constant.BossUserEnum;
import com.meilai.project.entity.business.contract.ContractApply;
import com.meilai.project.entity.business.customer.CustomerInfo;
import com.meilai.project.entity.business.workbench.SaleWeekCustomerTarget;
import com.meilai.project.entity.business.workbench.SaleWeekTarget;
import com.meilai.project.entity.business.workbench.Year;
import com.meilai.project.entity.business.workbench.YearWeek;
import com.meilai.project.mapper.business.contract.ContractApplyMapper;
import com.meilai.project.mapper.business.workbench.YearMapper;
import com.meilai.project.service.business.customer.CustomerInfoService;
import com.meilai.project.service.business.workbench.CompanyYearService;
import com.meilai.project.service.business.workbench.SaleWeekCustomerTargetService;
import com.meilai.project.service.business.workbench.SaleWeekTargetService;
import com.meilai.project.service.business.workbench.YearWeekService;
import com.meilai.project.vo.business.workbench.CompanyMonthTargetSummaryVO;
import com.meilai.project.vo.business.workbench.CompanyYearTargetSummaryVO;
import com.meilai.project.vo.business.workbench.WeekSummaryVO;
import com.meilai.project.vo.business.workbench.WeekTransactedCustomerVO;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class CompanyYearServiceImpl implements CompanyYearService {

    private final static BigDecimal ten_thousand = new BigDecimal(10000);

    @Autowired
    private YearMapper yearMapper;

    @Autowired
    private YearWeekService yearWeekService;

    @Autowired
    private ContractApplyMapper contractApplyMapper;

    @Autowired
    private CustomerInfoService customerInfoService;

    @Autowired
    private SaleWeekTargetService saleWeekTargetService;

    @Autowired
    private SaleWeekCustomerTargetService saleWeekCustomerTargetService;

    @Override
    public CompanyYearTargetSummaryVO queryCompanyYearTargetSummary(Integer year, Integer type) {
        BigDecimal hundred = new BigDecimal(100);
        List<Long> boss_ids = new ArrayList<>(Arrays.asList(BossUserEnum.values())).stream().map(BossUserEnum::getId).collect(Collectors.toList());
        LocalDate begin_date, end_date;
        if (type == 1) {
            begin_date = LocalDate.of(year, 1, 1);
            end_date = LocalDate.of(year, 6, 30);
        } else if (type == 2) {
            begin_date = LocalDate.of(year, 7, 1);
            end_date = LocalDate.of(year, 12, 31);
        } else {
            begin_date = LocalDate.of(year, 1, 1);
            end_date = LocalDate.of(year, 12, 31);
        }
        // 先查询出年度数据
        List<Year> yearList = yearMapper.selectList(Wrappers.<Year>lambdaQuery().eq(Year::getYear, year).eq(type != 3, Year::getType, type));
        CompanyYearTargetSummaryVO vo = new CompanyYearTargetSummaryVO();
        vo.setYear(year.toString());
        vo.setType(type);
        if (CollectionUtils.isEmpty(yearList)) {
            return vo;
        }
        List<Long> year_ids = yearList.stream().map(Year::getId).collect(Collectors.toList());
        // 统计年度目标
        BigDecimal sum = new BigDecimal(0);
        for (Year item : yearList) {
            sum = sum.add(item.getTarget());
        }
        vo.setSum(sum);
        // 查询周数据
        List<YearWeek> weekList = yearWeekService.list(Wrappers.<YearWeek>lambdaQuery().in(YearWeek::getYear_id, year_ids));
        // 找出需要查询的周id集合
        List<Long> week_ids = weekList.stream().map(YearWeek::getId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(week_ids)) {
            week_ids.add(-1L);
        }
        // 查询出所有销售每周的目标
        Map<Long, List<SaleWeekTarget>> sale_week_target_map = saleWeekTargetService.list(Wrappers.<SaleWeekTarget>lambdaQuery().in(SaleWeekTarget::getWeek_id, week_ids)).stream().collect(Collectors.groupingBy(SaleWeekTarget::getWeek_id));
        // 查出所有的客户
        List<CustomerInfo> customer_info_list = customerInfoService.list(Wrappers.<CustomerInfo>lambdaQuery().isNull(CustomerInfo::getDeleted_at));
        Map<Long, CustomerInfo> customer_info_map = customer_info_list.stream().collect(Collectors.toMap(CustomerInfo::getId, Function.identity()));
        List<Long> customer_ids = customer_info_list.stream().map(CustomerInfo::getId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(customer_ids)) {
            customer_ids.add(-1L);
        }
        Map<Long, List<SaleWeekCustomerTarget>> sale_week_customer_target_map = saleWeekCustomerTargetService.list(Wrappers.<SaleWeekCustomerTarget>lambdaQuery().in(SaleWeekCustomerTarget::getWeek_id, week_ids).in(SaleWeekCustomerTarget::getCustomer_id, customer_ids)).stream().collect(Collectors.groupingBy(SaleWeekCustomerTarget::getWeek_id));
        // 查询出合同
        List<ContractApply> contractApplyList = contractApplyMapper.queryEffectiveContractList(begin_date, end_date, customer_ids);
        // 统计年度的每月的数据
        List<CompanyMonthTargetSummaryVO> month_target_list = new ArrayList<>();
        BigDecimal year_amount_completed = new BigDecimal(0);
        BigDecimal zero = new BigDecimal(0).setScale(2, RoundingMode.HALF_UP);
        List<WeekSummaryVO> weekCompletionDetailVOList = new ArrayList<>();
        // 月度完成金额map
        Map<Integer, BigDecimal> month_amount_completed_map = new HashMap<>();
        // 月度维护完成金额map
        Map<Integer, BigDecimal> month_uphold_completed_map = new HashMap<>();
        // 月度个人完成金额map
        Map<Integer, BigDecimal> month_personal_completed_map = new HashMap<>();
        // 月度维护目标map
        Map<Integer, BigDecimal> month_uphold_target_map = new HashMap<>();
        // 月度个人目标map
        Map<Integer, BigDecimal> month_personal_target_map = new HashMap<>();
        // 组装数据
        for (YearWeek week : weekList) {
            WeekSummaryVO weekSummaryVO = new WeekSummaryVO();
            weekSummaryVO.setWeek_id(week.getId());
            weekSummaryVO.setBegin_date(week.getBegin_date());
            weekSummaryVO.setEnd_date(week.getEnd_date());
            weekSummaryVO.setMonth(week.getMonth());
            // 找出本周目标客户
            List<SaleWeekCustomerTarget> saleWeekCustomerTargetList = sale_week_customer_target_map.getOrDefault(week.getId(), new ArrayList<>());
            List<WeekTransactedCustomerVO> list = saleWeekCustomerTargetList.stream().map(item -> {
                WeekTransactedCustomerVO customerVO = new WeekTransactedCustomerVO();
                customerVO.setId(item.getCustomer_id());
                customerVO.setTarget(item.getTarget_quota());
                if (customer_info_map.containsKey(item.getCustomer_id())) {
                    customerVO.setName(customer_info_map.get(item.getCustomer_id()).getName());
                } else {
                    customerVO.setName("未知客户");
                }
                return customerVO;
            }).collect(Collectors.toList());
            // 本周的维护目标金额
            BigDecimal uphold_target = new BigDecimal(0);
            // 本周的个人目标金额
            BigDecimal personal_target = new BigDecimal(0);
            for (WeekTransactedCustomerVO weekTransactedCustomerVO : list) {
                CustomerInfo customerInfo = customer_info_map.get(weekTransactedCustomerVO.getId());
                if (customerInfo != null && boss_ids.contains(customerInfo.getPerson_in_charge_id())) {// 如果是公司客户
                    uphold_target = uphold_target.add(weekTransactedCustomerVO.getTarget());
                } else if (customerInfo != null && !boss_ids.contains(customerInfo.getPerson_in_charge_id())) { // 如果是个人客户
                    personal_target = personal_target.add(weekTransactedCustomerVO.getTarget());
                }
            }
            // 统计本周的目标
            List<SaleWeekTarget> weekTargetList = sale_week_target_map.getOrDefault(week.getId(), new ArrayList<>());
            BigDecimal week_target_summary = new BigDecimal(0);
            for (SaleWeekTarget saleWeekTarget : weekTargetList) {
                week_target_summary = week_target_summary.add(saleWeekTarget.getTarget_quota());
            }
            weekSummaryVO.setTarget(week_target_summary);
            // 统计本周的完成金额
            List<ContractApply> week_contract = contractApplyList.stream().filter(contract -> (contract.getSign_date().isBefore(week.getEnd_date()) || contract.getSign_date().equals(week.getEnd_date())) && contract.getSign_date().isAfter(week.getBegin_date()) || contract.getSign_date().equals(week.getBegin_date())).collect(Collectors.toList());
            // todo 本周目标客户修改为成交客户
            Map<Long, WeekTransactedCustomerVO> map = new HashMap<>();
            for (ContractApply contractApply : week_contract) {
                if (map.containsKey(contractApply.getCustomer_id())) {
                    WeekTransactedCustomerVO weekTransactedCustomerVO = map.get(contractApply.getCustomer_id());
                    weekTransactedCustomerVO.setTarget(weekTransactedCustomerVO.getTarget().add(contractApply.getDiscounted_price().divide(ten_thousand, 2, RoundingMode.HALF_UP)));
                    map.put(contractApply.getCustomer_id(), weekTransactedCustomerVO);
                } else {
                    WeekTransactedCustomerVO customerVO = new WeekTransactedCustomerVO();
                    customerVO.setId(contractApply.getCustomer_id());
                    customerVO.setTarget(contractApply.getDiscounted_price().divide(ten_thousand, 2, RoundingMode.HALF_UP));
                    if (customer_info_map.containsKey(contractApply.getCustomer_id())) {
                        customerVO.setName(customer_info_map.get(contractApply.getCustomer_id()).getName());
                    } else {
                        customerVO.setName("未知客户");
                    }
                    map.put(contractApply.getCustomer_id(), customerVO);
                }
            }
            weekSummaryVO.setWeekTransactedCustomerVOList(new ArrayList<>(map.values()));
            BigDecimal completed_amount = new BigDecimal(0);
            BigDecimal uphold_completed_amount = new BigDecimal(0);
            BigDecimal personal_completed_amount = new BigDecimal(0);
            for (ContractApply contractApply : week_contract) {
                completed_amount = completed_amount.add(contractApply.getDiscounted_price());
                CustomerInfo customerInfo = customer_info_map.get(contractApply.getCustomer_id());
                if (customerInfo != null && boss_ids.contains(customerInfo.getPerson_in_charge_id())) {// 如果是公司客户
                    uphold_completed_amount = uphold_completed_amount.add(contractApply.getDiscounted_price());
                } else if (customerInfo != null && !boss_ids.contains(customerInfo.getPerson_in_charge_id())) { // 如果是个人客户
                    personal_completed_amount = personal_completed_amount.add(contractApply.getDiscounted_price());
                }
            }
            // 换算成万元
            completed_amount = completed_amount.divide(ten_thousand, 2, RoundingMode.HALF_UP);
            uphold_completed_amount = uphold_completed_amount.divide(ten_thousand, 2, RoundingMode.HALF_UP);
            personal_completed_amount = personal_completed_amount.divide(ten_thousand, 2, RoundingMode.HALF_UP);
            weekSummaryVO.setCompleted_amount(completed_amount);
            // 计算本周完成率
            if (week_target_summary.compareTo(zero) > 0) {
                weekSummaryVO.setCompleted_rate(completed_amount.multiply(hundred).divide(week_target_summary, 2, RoundingMode.HALF_UP));
            } else {
                weekSummaryVO.setCompleted_rate(zero);
            }
            // 统计月度总完成金额
            month_amount_completed_map.put(week.getMonth(), completed_amount.add(month_amount_completed_map.getOrDefault(week.getMonth(), zero)));
            // 统计月度维护完成金额
            month_uphold_completed_map.put(week.getMonth(), uphold_completed_amount.add(month_uphold_completed_map.getOrDefault(week.getMonth(), zero)));
            // 统计月度个人完成金额
            month_personal_completed_map.put(week.getMonth(), personal_completed_amount.add(month_personal_completed_map.getOrDefault(week.getMonth(), zero)));
            // 统计月度维护目标
            month_uphold_target_map.put(week.getMonth(), uphold_target.add(month_uphold_target_map.getOrDefault(week.getMonth(), zero)));
            // 统计月度个人目标
            month_personal_target_map.put(week.getMonth(), personal_target.add(month_personal_target_map.getOrDefault(week.getMonth(), zero)));
            weekCompletionDetailVOList.add(weekSummaryVO);
        }
        // 按照月进行分组
        Map<Integer, List<WeekSummaryVO>> listMap = weekCompletionDetailVOList.stream().collect(Collectors.groupingBy(WeekSummaryVO::getMonth));
        Set<Integer> keys = listMap.keySet();
        for (Integer key : keys) {
            CompanyMonthTargetSummaryVO monthTargetVO = new CompanyMonthTargetSummaryVO();
            monthTargetVO.setMonth(key);
            List<WeekSummaryVO> tmp = listMap.get(key);
            BigDecimal target = new BigDecimal(0);
            for (WeekSummaryVO weekCompletionDetailVO : tmp) {
                target = target.add(weekCompletionDetailVO.getTarget());
            }
            monthTargetVO.setTarget(target);
            BigDecimal uphold_target = month_uphold_target_map.getOrDefault(key, zero);
            monthTargetVO.setUphold_target(uphold_target);
            BigDecimal personal_target = month_personal_target_map.getOrDefault(key, zero);
            monthTargetVO.setPersonal_target(personal_target);
            BigDecimal uphold_completed = month_uphold_completed_map.getOrDefault(key, zero);
            monthTargetVO.setUphold_completed(uphold_completed);
            BigDecimal personal_completed = month_personal_completed_map.getOrDefault(key, zero);
            monthTargetVO.setPersonal_completed(personal_completed);
            BigDecimal amount_completed = month_amount_completed_map.getOrDefault(key, zero);
            if (amount_completed.compareTo(zero) > 0) {
                monthTargetVO.setPersonal_completed_proportion(personal_completed.multiply(hundred).divide(amount_completed, 2, RoundingMode.HALF_UP));
                monthTargetVO.setUphold_completed_proportion(uphold_completed.multiply(hundred).divide(amount_completed, 2, RoundingMode.HALF_UP));
            } else {
                monthTargetVO.setPersonal_completed_proportion(zero);
                monthTargetVO.setUphold_completed_proportion(zero);
            }
            if (target.compareTo(zero) > 0) {
                monthTargetVO.setAmount_completed(amount_completed);
                monthTargetVO.setCompletion_rate(amount_completed.multiply(hundred).divide(monthTargetVO.getTarget(), 2, RoundingMode.HALF_UP));
                monthTargetVO.setPersonal_target_proportion(personal_target.multiply(hundred).divide(target, 2, RoundingMode.HALF_UP));
                monthTargetVO.setUphold_target_proportion(uphold_target.multiply(hundred).divide(target, 2, RoundingMode.HALF_UP));
            } else {
                monthTargetVO.setAmount_completed(zero);
                monthTargetVO.setCompletion_rate(zero);
                monthTargetVO.setPersonal_target_proportion(zero);
                monthTargetVO.setUphold_target_proportion(zero);
            }
            year_amount_completed = year_amount_completed.add(amount_completed);
            monthTargetVO.setWeekSummaryVOList(listMap.getOrDefault(key, new ArrayList<>()));
            month_target_list.add(monthTargetVO);
        }
        vo.setMonth_target_list(month_target_list);
        vo.setAmount_completed(year_amount_completed);
        if (vo.getSum().compareTo(zero) > 0) {
            vo.setCompletion_rate(vo.getAmount_completed().multiply(hundred).divide(vo.getSum(), 2, RoundingMode.HALF_UP));
        } else {
            vo.setCompletion_rate(zero);
        }
        return vo;
    }
}
